import { getServiceTaskLikeBusinessObject, getImplementationType, getConnector } from './bpmnPropertyUtils/eventDefinition'
import { getInputParameters, getOutputParameters, getInputOutput, CreateParameterCmd, editInputOutputParameter } from './dataInputOutput'
import { createModdleElement } from './bpmnPropertyUtils/extensionElements'
import { useSettingStore } from '@/store/bpmnProcess/settingStore'
import { useModelerStore } from '@/store/bpmnProcess/modelerStore'
import { without } from 'min-dash'

export function areConnectorsSupported(element) {
  const businessObject = getServiceTaskLikeBusinessObject(element)
  return businessObject && getImplementationType(businessObject) === 'connector'
}

export function getConnectorInput(element) {
  const connector = getConnector(element)
  return getInputParameters(connector) || []
}

export function addConnectorInputParameter(element, options) {
  const prefix = useSettingStore().editor.processEngine
  AddParameterCmd(element, `${prefix}:InputParameter`, options)
}

export function editConnectorInputParameter(element, options, index) {
  const prefix = useSettingStore().editor.processEngine
  editInputOutputParameter(element, options, index, `${prefix}:InputParameter`)
}

export function removeConnectorInputParameters(element, parameter) {
  removeInputOutputParameters(element, parameter, 'inputParameters')
}

export function getConnectorOutput(element) {
  const connector = getConnector(element)
  return getOutputParameters(connector) || []
}

export function addConnectorOutputParameter(element, options) {
  const prefix = useSettingStore().editor.processEngine
  AddParameterCmd(element, `${prefix}:OutputParameter`, options)
}

export function editConnectorOutputParameter(element, options, index) {
  const prefix = useSettingStore().editor.processEngine
  editInputOutputParameter(element, options, index, `${prefix}:OutputParameter`)
}

export function removeConnectorOutputParameters(element, parameter) {
  removeInputOutputParameters(element, parameter, 'outputParameters')
}

function AddParameterCmd(element, type, options) {
  const prefix = useSettingStore().editor.processEngine
  const modeling = useModelerStore().getModeling
  const connector = getConnector(element)
  // (1) ensure inputOutput
  let inputOutput = getInputOutput(connector)
  if (!inputOutput) {
    inputOutput = createModdleElement(`${prefix}:InputOutput`, { inputParameters: [], outputParameters: [] }, connector)
    modeling.updateModdleProperties(element, connector, { inputOutput })
  }

  // (2) create + add parameter
  CreateParameterCmd(element, type, inputOutput, options)
}

export function removeInputOutputParameters(element, parameter, type) {
  const modeling = useModelerStore().getModeling
  const connector = getConnector(element)
  const inputOutput = getInputOutput(connector)
  if (!inputOutput) {
    return
  }
  const parameterList = inputOutput.get(type)
  const newValue = without(parameterList, parameter)
  modeling.updateModdleProperties(element, inputOutput, { [type]: newValue })
}
